﻿using DG.Tweening;
using System;
using System.Collections.Generic;
using UnityEngine;

public class WaypointAnimation : MonoBehaviour {
    public float rotationDuration = 0.5f;
    public Waypoint[] waypoints;
    public Waypoint[] waypointsReverse;

    Transform _transform;
    int _currentIndex;
    Waypoint[] _waypoints;

    void Awake() {
        Forward();
    }

    public void Forward() {
        _transform = GetComponent<Transform>();
        _waypoints = waypoints;
    }

    public void Reverse() {
        _transform = GetComponent<Transform>();
        _waypoints = waypointsReverse;
    }

    public void ToEnd(Action callback = null) {
        WaypointTween(false, callback);
    }

    public void ToNext(Action callback = null) {
        WaypointTween(true, callback);
    }

    int _stepCount;

    public void ToStep(int steps, Action callback = null) {
        if (_stepCount >= steps) {
            if (callback != null) {
                callback();
            }

            _stepCount = 0;
            return;
        }

        ToNext(() => {
            _stepCount += 1;
            ToStep(steps, callback);
        });
    }

    public void JumpTo(int index, Action callback = null) {
        _currentIndex = index;
        WaypointTween(true, callback);
    }

    public void JumpToEnd(Action callback = null) {
        JumpTo(_waypoints.Length - 1, callback);
    }

    void WaypointTween(bool stepByStep, Action callback) {
        var point = _waypoints[_currentIndex];

        _transform.DORotate(point.target.localEulerAngles, rotationDuration).OnComplete(() => {
            _transform.DOMove(point.target.position, point.duration).SetEase(Ease.Linear).OnComplete(() => {
                _currentIndex += 1;
 
                if (_currentIndex >= _waypoints.Length) {
                    if (callback != null) {
                        callback();
                    }

                    _currentIndex = 0;
                    return;
                }

                if (!stepByStep) {
                    WaypointTween(stepByStep, callback);
                } else {
                    if (callback != null) {
                        callback();
                    }
                }
            });
        });
    }
}

[Serializable]
public class Waypoint {
    public Transform target;
    public float duration;
}
